home *** CD-ROM | disk | FTP | other *** search
/ Libris Britannia 4 / science library(b).zip / science library(b) / CUGUK / GAMES / C014.ZIP / LARN_SRC.ZIP / TOK.C < prev    next >
C/C++ Source or Header  |  1993-11-17  |  13KB  |  519 lines

  1. /* tok.c */
  2. /*
  3.    yylex()
  4.    flushall()
  5.    sethard()
  6.    readopts()
  7.    actual_readopts()
  8. */
  9. #ifdef VMS
  10. #include <types.h>
  11. #include <file.h>
  12. #include <iodef.h>
  13. #else VMS
  14. #include <sys/types.h>
  15. #ifdef SYSV
  16. #include <fcntl.h>
  17. # ifndef MSDOS
  18. #   include <termio.h>
  19. # endif
  20. #else SYSV
  21. # ifndef MSDOS
  22. #   include <sys/ioctl.h>
  23. # endif
  24. #endif SYSV
  25. #endif VMS
  26.  
  27. #include <ctype.h>
  28. #include "header.h"
  29. #include "larndefs.h"
  30. #include "monsters.h"
  31. #include "objects.h"
  32. #include "player.h"
  33.  
  34. #ifdef __STDC__
  35. static void actual_readopts( char*, char* );
  36. #else
  37. static void actual_readopts();
  38. #endif
  39.  
  40. # define CHKPTINT   400
  41.  
  42. static char lastok=0;
  43. int yrepcount=0;
  44. char move_no_pickup = FALSE ;
  45.  
  46. #ifdef TIMECHECK
  47. int dayplay=0;
  48. #endif TIMECHECK
  49.  
  50. #ifndef FLUSHNO
  51. #define FLUSHNO 5
  52. #endif FLUSHNO
  53. static int flushno=FLUSHNO; /* input queue flushing threshold */
  54. #define MAXUM 52    /* maximum number of user re-named monsters */
  55. #define MAXMNAME 40 /* max length of a monster re-name */
  56. static char usermonster[MAXUM][MAXMNAME]; /* the user named monster name goes here */
  57. static char usermpoint=0;           /* the user monster pointer */
  58. #ifdef MSDOS
  59.  extern int rawio;
  60. #endif
  61.  
  62. /*
  63.     lexical analyzer for larn
  64.  */
  65. yylex()
  66.     {
  67.     char cc;
  68.     int ic;
  69.     char firsttime = TRUE;
  70.  
  71.     if (hit2flag)
  72.         {
  73.         hit2flag=0;
  74.         yrepcount=0;
  75.         return(' ');
  76.         }
  77.     if (yrepcount>0)
  78.         {
  79.         --yrepcount;
  80.         return(lastok);
  81.         }
  82.     else
  83.         yrepcount=0;
  84.     if (yrepcount==0) 
  85.         { 
  86.         bottomdo(); 
  87.         showplayer();               /* show where the player is */
  88.         move_no_pickup = FALSE;     /* clear 'm' flag */
  89.         }
  90.  
  91.     lflush();
  92.     while (1)
  93.         {
  94.         c[BYTESIN]++;
  95.         if (ckpflag)
  96.           if ((c[BYTESIN] % CHKPTINT) == 0) /* check for periodic checkpointing */
  97.             {
  98. #ifndef DOCHECKPOINTS
  99. #ifdef MSDOS
  100.             cursors();
  101.             lprcat("\nCheckpointing . . .");
  102.             savegame(ckpfile);
  103.             lprcat("\nDone\n");
  104.             showplayer();
  105.             lflush();
  106.             lflushall(); /* Kill any stored key strokes */
  107. #else
  108. #ifdef VMS
  109.             savegame(ckpfile);
  110. #else
  111.             wait(0);    /* wait for other forks to finish */
  112.             if (fork() == 0) { savegame(ckpfile); exit(); }
  113. #endif
  114. #endif
  115. #else
  116. #ifdef VMS
  117.             savegame(ckpfile);
  118. #else
  119.             wait(0);    /* wait for other forks to finish */
  120.             if (fork() == 0) { savegame(ckpfile); exit(); }
  121. #endif
  122. #endif
  123.  
  124. #ifdef TIMECHECK
  125.             if (dayplay==0)
  126.               if (playable())
  127.                 {
  128.                 cursor(1,19);
  129.                 lprcat("\nSorry, but it is now time for work.  Your game has been saved.\n"); beep();
  130.                 lflush();
  131.                 savegame(savefilename);
  132.                 wizard=nomove=1;
  133.                 sleep(4);
  134.                 died(-257);
  135.                 }
  136. #endif TIMECHECK
  137.  
  138.             }
  139.  
  140. # ifndef MSDOS
  141. # ifdef VMS
  142.         /* If keyboard input buffer is too big then flush some? RDE */
  143.         /* Check this! but for now just ignore it... */
  144. # else
  145. #  ifndef SYSV
  146.         do /* if keyboard input buffer is too big, flush some of it */
  147.             {
  148.             ioctl(0,FIONREAD,&ic);
  149.             if (ic>flushno)   read(0,&cc,1);
  150.             }
  151.         while (ic>flushno);
  152. #  endif SYSV
  153. # endif VMS
  154. # endif MSDOS
  155.  
  156. # ifdef MSDOS
  157.         cc = ttgetch();
  158. # else MSDOS
  159. # ifdef VMS
  160.         cc = ttgetch();
  161. # else
  162.         if (read(0,&cc,1) != 1)
  163.             return(lastok = -1);
  164. # endif VMS
  165. # endif MSDOS
  166.         if (cc == '!')      /* ! shell escape */
  167.             {
  168.             resetscroll();  /* scrolling region, home, clear, no attributes */
  169.             clear();
  170. # ifdef MSDOS
  171.             doshell();
  172. # else MSDOS
  173. # ifdef VMS
  174.             lflush();
  175.             sncbr();
  176.             oneliner("");
  177.             scbr();
  178. # else VMS
  179.             lflush();
  180.             sncbr();
  181.             if ((ic=fork())==0) /* child */
  182.                 {
  183. #ifdef SYSV
  184.                 char *s, *getenv();
  185.                 if ((s=getenv("SHELL")) == (char *) 0)
  186.                     s = "/bin/sh";
  187.                 execl(s,"larn-shell", (char *)0);
  188.                 exit();
  189. #else
  190.                 execl("/bin/csh",0);
  191.                 exit();
  192.                 wait(0);
  193. #endif
  194.                 }
  195.             if (ic<0) /* error */
  196.                 {
  197.                 write(2,"Can't fork off a shell!\n",25);
  198.                 sleep(2);
  199.                 }
  200. #ifdef SYSV
  201.             else
  202.                 wait( (int *)0 );
  203. #endif SYSV
  204. # endif VMS
  205. # endif MSDOS
  206.             setscroll();
  207.             return(lastok = 'L'-64);    /* redisplay screen */
  208.             }
  209.  
  210.         /* get repeat count, showing to player
  211.         */
  212.         if ((cc <= '9') && (cc >= '0'))
  213.             {
  214.             yrepcount = yrepcount*10 + cc - '0';
  215.  
  216.             /* show count to player for feedback
  217.             */
  218.             if ( yrepcount >= 10 )
  219.                 {
  220.                 cursors();
  221.                 if (firsttime)
  222.                     lprcat("\n");
  223.                 lprintf("count: %d", (long)yrepcount );
  224.                 firsttime=FALSE;
  225.                 lflush();  /* show count */
  226.                 }
  227.             }
  228.         else
  229.             {
  230.             /* check for multi-character commands in command mode, and handle.
  231.             */
  232.             if ( cc == 'm' && !prompt_mode )
  233.                 {
  234.                 move_no_pickup = TRUE ;
  235.                 cc = ttgetch();
  236.                 }
  237.             if ( yrepcount > 0 )
  238.                 --yrepcount;
  239.             return(lastok = cc);
  240.             }
  241.         }
  242.     }
  243.  
  244. /*
  245.  *  flushall()  Function to flush all type-ahead in the input buffer
  246.  */
  247. lflushall()
  248.     {
  249. # ifdef MSDOS
  250.     while (kbhit())
  251.         getch();
  252. # else MSDOS
  253. # ifdef VMS
  254.     /* Flush all type-ahead -- RDE */
  255.     extern int  iochan;     /* defined in IO.C  */
  256.     int     c;
  257.  
  258.     SYS$QIOW(0,iochan,IO$_READLBLK|IO$M_TIMED|IO$M_PURGE,0,0,0,&c,1,0,0,0,0);
  259.  
  260. # else VMS
  261. #ifdef SYSV
  262.     ioctl(0,TCFLSH,0);
  263. #else
  264.     char cc;
  265.     int ic;
  266.     for (;;) {      /* if keyboard input buffer is too big, flush some of it */
  267.         ioctl(0,FIONREAD,&ic);
  268.         if (ic<=0)
  269.             return;
  270.         while (ic>0) {
  271.             read(0,&cc,1);
  272.             --ic;
  273.         } /* gobble up the byte */
  274.     }
  275. # endif SYSV
  276. # endif VMS
  277. # endif MSDOS
  278. }
  279.  
  280. /*
  281.     function to set the desired hardness
  282.     enter with hard= -1 for default hardness, else any desired hardness
  283.  */
  284. sethard(hard)
  285. int hard;
  286. {
  287.     register int    j,k;
  288.     long        i;
  289.     struct monst    *mp;
  290.  
  291.     j=c[HARDGAME]; hashewon();
  292.     if (restorflag==0)  /* don't set c[HARDGAME] if restoring game */
  293.         {
  294.         if (hard >= 0) c[HARDGAME]= hard;
  295.         }
  296.     else c[HARDGAME]=j; /* set c[HARDGAME] to proper value if restoring game */
  297.  
  298.     if (k=c[HARDGAME])
  299.       for (j=0; j<=MAXMONST+8; j++) {
  300.         mp = &monster[j];
  301.         i = ((6+k) * mp->hitpoints + 1)/6;
  302.         mp->hitpoints = (i<0) ? 32767 : i;
  303.         i = ((6+k) * mp->damage + 1) / 5;
  304.         mp->damage = (i>127) ? 127 : i;
  305.         i = (10 * mp->gold)/(10+k);
  306.         mp->gold = (i>32767) ? 32767 : i;
  307.         i = mp->armorclass - k;
  308.         mp->armorclass = (i< -127) ? -127 : i;
  309.         i = (7*mp->experience)/(7+k) + 1;
  310.         mp->experience = (i<=0) ? 1 : i;
  311.     }
  312. }
  313.  
  314.  
  315. /*
  316.     function to read and process the larn options file
  317. */
  318. readopts()
  319.     {
  320.     register int j;
  321.     char original_objects = FALSE ;
  322.     char namenotchanged = TRUE;     /* set to 0 if a name is specified */
  323.  
  324. # ifdef MSDOS
  325.     if (plopen(optsfile) < 0)
  326. # else
  327.     if (lopen(optsfile) < 0)
  328. # endif
  329.         {
  330.         lprintf("Can't open options file \"%s\"\n", optsfile);
  331.         lflush();
  332.         sleep(1);
  333.         }
  334.     else
  335.         actual_readopts(&namenotchanged, &original_objects);
  336.  
  337.     if (namenotchanged)
  338.         strcpy(logname,loginname);
  339.  
  340.     /* original objects require object highlighting to be ON (in order
  341.        to distinguish between objects and monsters).  set up object list
  342.        properly.
  343.     */
  344.     if (original_objects)
  345.         {
  346.         boldobjects = TRUE ;
  347.         strncpy( objnamelist, original_objnamelist, MAXOBJECT );
  348.         }
  349.     else
  350.         strncpy( objnamelist, hacklike_objnamelist, MAXOBJECT );
  351.     objnamelist[MAXOBJECT] = '\0' ;
  352.  
  353.     /* now set all the invisible objects and monsters to have the
  354.        same appearance as the floor (as defined by the user)
  355.     */
  356.     objnamelist[OWALL] = wallc;
  357.  
  358.     objnamelist[0]        =
  359.     objnamelist[OIVTELETRAP]  =
  360.     objnamelist[OTRAPARROWIV] =
  361.     objnamelist[OIVDARTRAP]   =
  362.     objnamelist[OIVTRAPDOOR]  = floorc;
  363.     monstnamelist[0] =
  364.     monstnamelist[INVISIBLESTALKER] = floorc;
  365.     for (j=DEMONLORD; j<=DEMONPRINCE; j++)
  366.         monstnamelist[j] = floorc;
  367.     }
  368.  
  369. static void actual_readopts( namenotchanged, original_objects )
  370. char *namenotchanged;
  371. char *original_objects;
  372.     {
  373.     register char *i;
  374.     register int j,k;
  375.  
  376.     i = " ";
  377.     while (*i)
  378.         {
  379.         /* check for EOF
  380.         */
  381.         if ((i=(char *)lgetw()) == 0)
  382.             return;
  383. #if 0
  384.         while (*i && ((*i==' ') || (*i=='\t'))) i++; /* eat leading whitespace */
  385. #endif
  386.         /* leading # a comment, eat the rest of the line.  Handle multiple
  387.            comment lines in a row.
  388.         */
  389.         while (*i == '#')
  390.             {
  391.             char cc;
  392.             do
  393.                 cc = (char)lgetc();
  394.             while ( ( cc != '\n' ) && ( cc != NULL));
  395.             if ((i = (char *)lgetw()) == 0)
  396.                 return;
  397.             }
  398.  
  399.         if (strcmp(i,"bold-objects") == 0)
  400.             boldon=1;
  401.         else if (strcmp(i,"enable-checkpointing") == 0)
  402.             ckpflag=1;
  403.         else if (strcmp(i,"inverse-objects") == 0)
  404.             boldon=0;
  405.         else if (strcmp(i,"prompt-on-objects") == 0 )
  406.             prompt_mode = TRUE ;
  407.         else if (strcmp(i,"auto-pickup") == 0 )
  408.             auto_pickup = TRUE ;
  409.         else if (strcmp(i,"highlight-objects") == 0 )
  410.             boldobjects = TRUE ;
  411.         else if (strcmp(i,"original-objects") == 0 )
  412.             *original_objects = TRUE ;
  413.         else if (strcmp(i,"female") == 0)
  414.             sex=0; /* male or female */
  415. # ifdef MSDOS
  416.         else if (strcmp(i, "graphics:") == 0)
  417.             {
  418.             wallc = atoi(lgetw());
  419.             floorc = atoi(lgetw());
  420.             }
  421.         else if (strcmp(i, "larndir:") == 0)
  422.             {
  423.             if ((i=lgetw())==0)
  424.                 break;
  425.             strncpy(larndir, i, DIRLEN);
  426.             larndir[DIRLEN - 1] = 0;
  427.             }
  428.         else if (strcmp(i, "rawio") == 0)
  429.             rawio = 1;
  430.         else if (strcmp(i, "swapfile:") == 0)
  431.             {
  432.             if ((i = (char *)lgetw()) == 0)
  433.                 break;
  434.             strncpy(swapfile, i, PATHLEN);
  435.             swapfile[PATHLEN - 1] = 0;
  436.             }
  437.         else if (strcmp(i, "ramlevels:") == 0)
  438.             ramlevels = atoi(lgetw());
  439.         else if (strcmp(i, "cursor:") == 0)
  440.             {
  441.             cursorset = 1;
  442.             cursorstart = (unsigned char) atoi(lgetw());
  443.             cursorend = (unsigned char) atoi(lgetw());
  444.             }
  445.         else if (strcmp(i, "keypad") == 0)
  446.             keypad = 1;
  447.         else if (strcmp(i, "DECRainbow") == 0)
  448.             DECRainbow = 1;
  449. # endif
  450.         else if (strcmp(i,"monster:")== 0)   /* name favorite monster */
  451.             {
  452.             if ((i=(char *)lgetw())==0)
  453.                 break;
  454.             if (strlen(i)>=MAXMNAME)
  455.                 i[MAXMNAME-1]=0;
  456.             strcpy(usermonster[usermpoint],i);
  457.             if (usermpoint >= MAXUM)
  458.                 break; /* defined all of em */
  459.             if (isalpha(j=usermonster[usermpoint][0]))
  460.                 {
  461.                 for (k=1; k<MAXMONST+8; k++) /* find monster */
  462.                   if (monstnamelist[k] == j)
  463.                     {
  464.                     monster[k].name = &usermonster[usermpoint++][0];
  465.                     break;
  466.                     }
  467.                 }
  468.             }
  469.         else if (strcmp(i,"male") == 0)
  470.             sex=1;
  471.         else if (strcmp(i,"name:") == 0) /* defining players name */
  472.             {
  473.             if ((i=lgetw())==0)
  474.                 break;
  475.             if (strlen(i)>=LOGNAMESIZE)
  476.                 i[LOGNAMESIZE-1]=0;
  477.             strcpy(logname,i);
  478.             *namenotchanged = FALSE;
  479. # ifdef MSDOS
  480.             strcpy(loginname,i);
  481. # endif
  482.             }
  483.         else if (strcmp(i,"no-introduction") == 0)
  484.             nowelcome=1;
  485.         else if (strcmp(i,"no-beep") == 0)
  486.             nobeep=1;
  487. # ifndef MSDOS
  488.         else if (strcmp(i,"process-name:")== 0)
  489.             {
  490.             if ((i=lgetw())==0)
  491.                 break;
  492.             if (strlen(i)>=PSNAMESIZE)
  493.                 i[PSNAMESIZE-1]=0;
  494.             strcpy(psname,i);
  495.             }
  496.         else if (strcmp(i,"play-day-play") == 0)
  497. # ifdef TIMECHECK
  498.             dayplay=1;
  499. # else
  500.         ;
  501. # endif
  502. # endif
  503.         else if (strcmp(i,"savefile:") == 0) /* defining savefilename */
  504.             {
  505.             if ((i=lgetw())==0)
  506.                 break;
  507.             if (strlen(i)>=SAVEFILENAMESIZE) /* avoid overflow */
  508.                 i[SAVEFILENAMESIZE-1]=0;
  509.             strcpy(savefilename,i);
  510.             }
  511.         else
  512.             {
  513.             lprintf("Unknown option \"%s\"\n", i);
  514.             lflush();
  515.             sleep(1);
  516.             }
  517.         }
  518.     }
  519.